package com.qh.paythird.mofang;

import com.alibaba.fastjson.JSONObject;
import com.qh.common.utils.EmptyUtil;
import com.qh.common.utils.R;
import com.qh.pay.api.Order;
import com.qh.pay.api.PayConstants;
import com.qh.pay.api.constenum.OrderParamKey;
import com.qh.pay.api.constenum.OrderState;
import com.qh.pay.api.constenum.OutChannel;
import com.qh.pay.api.constenum.YesNoType;
import com.qh.pay.api.utils.ParamUtil;
import com.qh.pay.api.utils.RequestUtils;
import com.qh.pay.service.PayService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.security.SignatureException;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

@Service
public class MofangService {
    private static final Logger logger = LoggerFactory.getLogger(MofangService.class);

    public R order(Order order) {
        Map<String, String> requestMap = new HashMap<>(16);
        requestMap.put("merchant_order_sn", order.getOrderNo());
        requestMap.put("paychannel_type", this.getPaychannelType(order.getOutChannel()));
        requestMap.put("trade_amount", ParamUtil.yuanToFen(order.getAmount()));
        requestMap.put("merchant_notify_url", PayService.commonNotifyUrl(order));
        requestMap.put("ord_name", EmptyUtil.isEmpty(order.getMemo()) ?"":order.getMemo());
        requestMap.put("interface_type", MofangConst.interface_type_1);
        //前端返回地址
        requestMap.put("merchant_return_url", PayService.commonReturnUrl(order));

        try {
            Map<String, Object> responseMap = PaymentUtil.sendDirectPayPost(requestMap);
            R r = handlerResult(responseMap);
            if(R.ifError(r)){
                return r;
            }
            JSONObject jsonObject = JSONObject.parseObject((String) responseMap.get("data"));
            Map<String, String> resultMap = PayService.initRspData(order);
            order.setBusinessNo(jsonObject.getString("order_sn"));
            if(EmptyUtil.isNotEmpty(order.getBusinessNo())){
                requestMap.put(OrderParamKey.businessNo.name(),order.getBusinessNo());
            }
            resultMap.put(PayConstants.web_qrcode_url, jsonObject.getString("out_pay_url"));
            return R.okData(resultMap);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(e.getMessage());
            return R.error("支付失败:" + e.getMessage());
        }
    }

    public R notify(Order order, HttpServletRequest request, String requestBody) {
        Map<String, String> requestMap = RequestUtils.getAllRequestParamStream(request);
        logger.info("mofangceo支付回调结果：{}", requestMap);
        String sign = requestMap.get("sign");
        requestMap.remove("sign");
        String data = Tools.getUrlParamsByMap(new TreeMap<>(requestMap))
                .replaceAll("\\\\/", "/").replaceAll("\\\\\\\\", "\\\\");
        try {
            logger.info("verify====>" + RSAUtils.doCheck(data, sign, PaymentUtil.getPtPublicKey(), "utf-8", PaymentUtil.getAlgorithm()));
        } catch (SignatureException e) {
            e.printStackTrace();
            logger.error("mofangceo支付回调验签返回失败");
            return R.error("支付回调验签返回失败");
        }
        String amount = requestMap.get("trade_amount");
        if (ParamUtil.isNotEmpty(amount)) {
            order.setRealAmount(ParamUtil.fenToYuan(amount));
        }
        String pay_status = requestMap.get("pay_status");
        if(MofangConst.pay_status_succ.equals(pay_status)){
            order.setOrderState(OrderState.succ.id());
        }
        return R.ok();
    }

    public R query(Order order) {
        Map<String, String> requestMap = new HashMap<>(16);
        requestMap.put("merchant_order_sn", order.getOrderNo());
        try {
            Map<String, Object> responseMap = PaymentUtil.sendDirectQueryPost(requestMap);
            R r = handlerResult(responseMap);
            if(R.ifError(r)){
                return r;
            }
            JSONObject jsonObject = JSONObject.parseObject((String) responseMap.get("data"));
            String pay_status = jsonObject.getString("pay_status");
            if(MofangConst.pay_status_succ.equals(pay_status)){
                order.setOrderState(OrderState.succ.id());
            }
            String order_sn = jsonObject.getString("order_sn");
            if(EmptyUtil.isEmpty(order.getBusinessNo())){
                order.setBusinessNo(order_sn);
            }
            return R.ok();
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(e.getMessage());
            return R.error("支付订单查询失败:" + e.getMessage());
        }
    }

    public R orderAcp(Order order) {
        String bankCode = order.getBankCode();
        Map<String, String> requestMap = new HashMap<>();
        requestMap.put("id_card_no", order.getCertNo());
        requestMap.put("merchant_order_sn", order.getOrderNo());
        requestMap.put("out_proxy_amount", ParamUtil.yuanToFen(order.getAmount()));
        requestMap.put("receive_name", order.getAcctName());
        requestMap.put("receive_account", order.getBankNo());
        requestMap.put("receive_bank", PaymentUtil.gbEncoding(MofangConst.bkDesc().get(bankCode)));
        requestMap.put("bank_code", MofangConst.bkCode().get(bankCode));
        requestMap.put("receive_bank", PaymentUtil.gbEncoding(order.getBankBranch()));
        requestMap.put("receive_account_type", MofangConst.receive_account_type_pri);
        requestMap.put("receive_phone", order.getMobile());
        requestMap.put("remark", EmptyUtil.isEmpty(order.getMemo()) ?"":order.getMemo());
        try {
            Map<String, Object> responseMap = PaymentUtil.sendProxyPayPost(requestMap);
            R r = handlerResult(responseMap);
            if(R.ifError(r)){
                return r;
            }
            JSONObject jsonObject = JSONObject.parseObject((String) responseMap.get("data"));
            String pay_status = jsonObject.getString("pay_status");
            if(MofangConst.pay_status_acp_paying.equalsIgnoreCase(pay_status)){
                order.setOrderState(OrderState.ing.id());
            }
            String order_sn = jsonObject.getString("order_sn");
            if(EmptyUtil.isEmpty(order.getBusinessNo())){
                order.setBusinessNo(order_sn);
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(e.getMessage());
            return R.error("订单代付受理失败:" + e.getMessage());
        }
        return R.ok();
    }

    private static R handlerResult(Map<String, Object> responseMap ){
        if(responseMap == null){
            return R.error("支付失败！");
        }
        String errcode = String.valueOf(responseMap.get("errcode"));
        String isVerify = (String) responseMap.get("isVerify");
        if(!MofangConst.error_code_succ.equalsIgnoreCase(errcode)){
            return R.error("支付返回失败");
        }
        if(!String.valueOf(YesNoType.yes.id()).equals(isVerify)){
            return R.error("支付返回验签失败");
        }
        String data = (String) responseMap.get("data");
        if(EmptyUtil.isEmpty(data)){
            return R.error("返回数据为空！");
        }
        return R.ok();
    }


    private String getPaychannelType(String outChannel){
        if(OutChannel.wxpayqrcode.name().equalsIgnoreCase(outChannel)){
            return MofangConst.PMT_weixin_qrcode;
        }
        if(OutChannel.alipayqrcode.name().equalsIgnoreCase(outChannel)){
            return MofangConst.PMT_alipay_qrcode;
        }
        if(OutChannel.qq.name().equalsIgnoreCase(outChannel)){
            return MofangConst.PMT_qq_qrcode;
        }
        if(OutChannel.wap.name().equalsIgnoreCase(outChannel)){
            return MofangConst.PMT_weixin_wap;
        }
        return "";

    };

    public R acpQuery(Order order) {
        Map<String, String> requestMap = new HashMap();
        requestMap.put("merchant_order_sn", order.getOrderNo());
        try {
            Map<String, Object> responseMap = PaymentUtil.sendProxyQueryPost(requestMap);
            R r = handlerResult(responseMap);
            if(R.ifError(r)){
                return r;
            }
            JSONObject jsonObject = JSONObject.parseObject((String) responseMap.get("data"));
            String pay_status = jsonObject.getString("pay_status");
            if(MofangConst.pay_status_acp_paying.equalsIgnoreCase(pay_status)){
                order.setOrderState(OrderState.ing.id());
            }
            if(MofangConst.pay_status_acp_PAYED.equalsIgnoreCase(pay_status)){
                order.setOrderState(OrderState.succ.id());
            }
            if(MofangConst.pay_status_acp_REFUND.equalsIgnoreCase(pay_status)){
                order.setOrderState(OrderState.fail.id());
            }
            String order_sn = jsonObject.getString("order_sn");
            if(EmptyUtil.isEmpty(order.getBusinessNo())){
                order.setBusinessNo(order_sn);
            }
            return R.ok();
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(e.getMessage());
            return R.error("代付订单查询失败:" + e.getMessage());
        }
    }


    public R notifyAcp(Order order, HttpServletRequest request, String requestBody) {
        return R.error("平台不受理代付通知请求！");
    }
}
